package pl.edu.agh.lab2.sr.main;

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.util.List;

import pl.edu.agh.lab2.sr.beans.GameAlreadyCreatedException;
import pl.edu.agh.lab2.sr.beans.InvalidUserException;
import pl.edu.agh.lab2.sr.game.GameMap;
import pl.edu.agh.lab2.sr.game.IBattleshipGame;
import pl.edu.agh.lab2.sr.player.IPlayer;
import pl.edu.agh.lab2.sr.player.Player;
import pl.edu.agh.lab2.sr.server.IBattleshipServer;

public class SamplePlayer {

	private static final String battleshipServerObjectPath = "rmi://127.0.0.1:1099/battleship";
	private IBattleshipServer server;
	private IPlayer player;
	private IBattleshipGame game;
	private int gameID;

	public static void main(String[] args) {
		if (args.length < 1) {
			System.err.println("missing nickname");
			return;
		}
		// if (System.getSecurityManager() == null) {
		// System.setSecurityManager(new SecurityManager());
		// }

		SamplePlayer sp = new SamplePlayer();
		sp.initData(args[0]);
		sp.menuLoop();
	}

	private void initData(String nick) {
		try {
			server = (IBattleshipServer) Naming
					.lookup(battleshipServerObjectPath);

			player = new Player(nick);
		} catch (Exception e) {
			System.out.println(e.toString());
		}

	}

	private void menuLoop() {
		while (true) {
			String input = System.console().readLine();
			try {
				switch (input) {
				case "quit": {
					handleQuit();
					break;
				}
				case "register": {
					handleRegister();
					break;
				}
				case "unregister": {
					handleUnregister();
					break;
				}
				case "listPlayers": {
					handleListRegisteredPlayers();
					break;
				}
				case "listGames": {
					handleListGames();
					break;
				}
				case "create": {
					handleCreateGame();
					break;
				}
				case "join": {
					handleJoinGame();
					break;
				}
				default: {
					System.out
							.println("Bad command. join listPlayers listGames register unregister quit create");
				}
				}
			} catch (Exception e) {
				System.err.println(e.getMessage());
			}
		}

	}

	private void handleJoinGame() throws RemoteException, InvalidUserException {
		System.out.println("Type game id: ");
		int gameId = Integer.parseInt(System.console().readLine());
		game = server.join(player, gameId);
		gameID = gameId;
		gameLoop();
	}

	private void handleListGames() throws RemoteException {
		List<String> games = server.getGamesList();
		System.out.println("Created games: " + games.size());
		for (String game : games) {
			System.out.println("   " + game);
		}
	}

	private void handleCreateGame() throws RemoteException,
			GameAlreadyCreatedException, InvalidUserException {
		gameID = server.createBattleshipGame(player);
		game = server.getGameById(gameID);
		gameLoop();
	}

	private void gameLoop() {
		while (true) {
			String input = System.console().readLine();
			try {
				switch (input) {
				case "quit": {
					handleQuit();
					break;
				}
				case "start": {
					handleStart();
					break;
				}
				case "listGames": {
					handleListGames();
					break;
				}

				case "finish": {
					handleFinishGame();
					break;
				}

				case "listAll": {
					handleListRegisteredPlayers();
					break;
				}
				case "listPlayers": {
					handleListPlayersInGame();
					break;
				}
				case "move": {
					handleMove();
					break;
				}
				case "initMap": {
					handleInitMap();
					break;
				}
				case "about" :{
					System.out.println(player.getAbout());
					break;
				}
				default: {
					System.out
							.println("Bad command: initMap quit listGames listAll listPlayers start finish move");
				}
				}
			} catch (Exception e) {
				System.err.println(e.getMessage());
			}
		}
	}

	private void handleInitMap() throws RemoteException {
		GameMap map = new GameMap();
		game.setMap(player, map);
	}

	private void handleListPlayersInGame() throws RemoteException {
		game = server.getGameById(gameID);
		IPlayer player1 = game.getPlayer1();
		IPlayer player2 = game.getPlayer2();

		System.out.println("P1: " + player1);
		System.out.println("P2: " + player2);

	}

	private void handleMove() throws RemoteException {
		game.nextMove();

	}

	private void handleFinishGame() throws RemoteException {
		game.finish();
	}

	private void handleStart() throws RemoteException {
		game = server.getGameById(gameID);
		game.start();
	}

	private void handleUnregister() throws RemoteException,
			InvalidUserException {
		server.unregister(player);
	}

	private void handleRegister() throws RemoteException, InvalidUserException {
		server.register(player);
	}

	private void handleQuit() {
		try {
			if (game != null) {
				server.removeGame(player);
			}
			handleUnregister();

		} catch (RemoteException | InvalidUserException e) {
			System.err.println(e.getMessage());
		}
		System.exit(0);
	}

	private void handleListRegisteredPlayers() throws RemoteException {
		List<String> players = server.getRegisteredPlayers();
		System.out.println("Players on server: " + players.size());
		for (String player : server.getRegisteredPlayers()) {
			System.out.println("   " + player);
		}
	}
}
